﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI.WebControls;
using System.Xml;
using YuzKitabi.Data;
using System.Reflection;
using System.ComponentModel;
using System.Data;
using System.Collections;

namespace YuzKitabi.WebApplication.UI.Controls
{
   public class MyGridView:WebControl
    {

        private object _datasource;
        private List<string> _columnNames;
        private List<List<string>> _dataList;


       [Browsable(true)]
       public string DataSourceName
       {
           get
           {
               if (ViewState["DataSourceName"] != null)
                   return ViewState["DataSourceName"] as string;
               return string.Empty;
           }
           set
           {
               ViewState["DataSourceName"] = value;
           }
       }




       protected override void Render(System.Web.UI.HtmlTextWriter writer)
       {
           try
           {
               _datasource = GetDataSource();

               if (NormalizeDatasource())
               {
                   writer.Write("<table>");
                   writer.Write("<thead>");
                   foreach (string column in _columnNames)
                   {
                       writer.Write("<th>" + column + "</th>");
                   }
                   writer.Write("</thead>");

                   foreach (List<string> item in _dataList)
                   {

                       writer.Write("<tr class='gridItem'>");

                       foreach (string s in item)
                       {
                           writer.Write("<td style='border-bottom-style:solid'> <a style='color:red'> " + s + "</a> </td>");
                       }

                       writer.Write("</tr>");
                   }
                   writer.Write("</table>");
               }

               else
               {
                   writer.Write("IList or DataTable expected..");
               }
           }

           catch (Exception ex)
           {
               writer.Write(ex.Message);
           }
       }


       private bool NormalizeDatasource()
       {
           try
           {
               if (_datasource is DataTable)
               {
                   DataTable dt = _datasource as DataTable;
                   _dataList = new List<List<string>>();
                   _columnNames = new List<string>();

                   foreach (DataColumn dc in dt.Columns)
                   {
                       _columnNames.Add(dc.ColumnName);
                   }

                   foreach (DataRow dr in dt.Rows)
                   {
                       List<string> rowItems = new List<string>();
                       for (int i = 0; i < dt.Columns.Count; i++)
                       {
                           rowItems.Add(dr[i].ToString());
                       }
                       _dataList.Add(rowItems);
                   }
                   return true;
               }

               else if (_datasource is IList)
               {
                   IList col = _datasource as IList;
                   IEnumerator enumerator = col.GetEnumerator();
                   _dataList = new List<List<string>>();
                   _columnNames = new List<string>();
                   while (enumerator.MoveNext())
                   {
                       object currentItem = enumerator.Current;
                       PropertyInfo[] props = currentItem.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
                       List<string> items = new List<string>();
                       foreach (PropertyInfo p in props)
                       {
                           if (!_columnNames.Contains(p.Name))
                           {
                               _columnNames.Add(p.Name);
                           }
                           items.Add(p.GetValue(currentItem).ToString());

                       }
                       _dataList.Add(items);
                   }
                   return true;
               }

               else
                   return false;
           }
           catch
           {
               throw new Exception();
           }

       }





       protected object GetDataSource()
       {
           IDataProvider dataProviderInstance = CreateDataSourceProviderInstance();

           if (dataProviderInstance != null)
           {
               object datasource = dataProviderInstance.GetData();
               return datasource;
           }

           return null;
       }

       protected XmlDocument ReadXml()
       {
           try
           {
               XmlDocument doc = new XmlDocument();
               doc.Load(this.Page.Server.MapPath("DataProviderConfig.xml"));
               return doc;
           }
           catch (Exception ex)
           {
               
               return null;
           }
       }

       protected string GetProviderType()
       {
           string datasource = this.DataSourceName;

           XmlDocument doc = ReadXml();

           if (doc != null)
           {
               XmlNode node = doc.SelectSingleNode("DataProviderDefinitions/Data[@name='" + datasource + "']/Impl");
               if (node != null && node.Attributes["name"] != null)
               {
                   return node.Attributes["type"].Value;
               }
               else
               {
                   return string.Empty;
               }
           }

           return string.Empty;

       }



       protected IDataProvider CreateDataSourceProviderInstance()
       {
           try
           {
               args = new string[4];
             
               string typeName = GetProviderType();
               Type _type = Type.GetType(typeName);
               IDataProvider instance = null;
               instance = Activator.CreateInstance(_type) as IDataProvider;
               return instance;
           }
           catch (Exception ex)
           {
               return null;
           }
       }

       private string[] args
       {
           get;
           set;
       }


    }
}
